package com.ocom.emqx.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ocom.common.entity.emqx.*;
import com.ocom.common.request.emqx.YhMqtt0606Request;
import com.ocom.common.request.emqx.YhMqtt0607Request;
import com.ocom.common.request.emqx.YhMqtt060ERequest;
import com.ocom.common.request.emqx.YhMqtt07Request;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.Date;

/**
 * emax转换工具
 */
@Slf4j
public class EmqxConvert {

    public static Date convertTime(String timeStr){
        int timeInt = DesUtils.hexToInt(timeStr);
        return new Date(timeInt * 1000L);
    }

    public static String formatConvertTime(String timeStr,String format){
        return DateUtil.format(convertTime(timeStr),format);
    }

    /**
     * 时间转成16进制，位数不够的补零
     * @param date
     * @param length
     * @return
     */
    public static String timeConvertToHex(Date date,int length){
        long timeInt =  (date.getTime()) / 1000;
        return DesUtils.intToHexWithFillZero((int) timeInt,length);  //时间戳，转16进制
    }


    public static String formatConvertTime(String timeStr){
        return formatConvertTime(timeStr,"yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 将16进制的订单号转换成10进制的订单号，并去零
     * @return
     */
    public static Long convertOrderNo(String orderNo){
        return DesUtils.hexToInt(orderNo).longValue();
    }

    /**
     * 84数据转换
     * @param message
     * @return
     */
    public static EntityYhMqtt84 convertYhMqtt84(String message){
        String org = checkMsg(message);
        EntityYhMqtt84 entityYhMqtt84 = new EntityYhMqtt84();
        entityYhMqtt84.setStatusHex(org.substring(14,16));
        entityYhMqtt84.setErrorStatusHex(org.substring(16,18));
        entityYhMqtt84.setStatus(Integer.parseInt(entityYhMqtt84.getStatusHex()));
        entityYhMqtt84.setErrorStatus(Integer.parseInt(entityYhMqtt84.getErrorStatusHex()));
        entityYhMqtt84.setSubString(org.substring(0,6));
        entityYhMqtt84.setRaw(message);
        entityYhMqtt84.setUnencryptedCommand(org);
        return entityYhMqtt84;
    }

    /**
     * 将设备换回的数据转换成类对象
     * @param message
     * @return
     */
    public static EntityYhMqtt86 convertYhMqtt86(String message){
        String resultMsg = checkMsg(message);
        log.info(resultMsg);
        String orderId = resultMsg.substring(14,22);
        String randCode = resultMsg.substring(22,30);
        String time = resultMsg.substring(30,38);
        String status = resultMsg.substring(12,14);
        EntityYhMqtt86 entityYhMqtt86 = new EntityYhMqtt86();
        entityYhMqtt86.setOrderNoHex(orderId);
        entityYhMqtt86.setRandomCode(randCode);
        entityYhMqtt86.setTimeHex(time);
        entityYhMqtt86.setTime(convertTime(time));
        entityYhMqtt86.setOrderNo(convertOrderNo(orderId));
        entityYhMqtt86.setStatus(DesUtils.hexToInt(status));
        entityYhMqtt86.setFormatTime(DateUtil.format(entityYhMqtt86.getTime(),"yyyy-MM-dd HH:mm:ss"));
        entityYhMqtt86.setStatusHex(status);
        return entityYhMqtt86;
    }

    /**
     * 0607 数据转换
     * @param yhMqtt0607Request
     * @return
     */
    public static EntityYhMqtt0607 convertYhMqtt0607(YhMqtt0607Request yhMqtt0607Request){

        EntityYhMqtt0607 entityYhMqtt0607 = Convert.convert(EntityYhMqtt0607.class,yhMqtt0607Request);
        entityYhMqtt0607.setOrderNoHex( DesUtils.intToHexWithFillZero(yhMqtt0607Request.getOrderNo().intValue(),4)); //固定8位数,目前全部转成16进制,并补零
        entityYhMqtt0607.setConsumptionModelHex(DesUtils.intToHexWithFillZero(7,1));  //模式
        entityYhMqtt0607.setBalanceHex( DesUtils.intToHexWithFillZero(0,4));  //余额，转16进制(需补零)
        entityYhMqtt0607.setLaundryModelHex(DesUtils.intToHexWithFillZero(yhMqtt0607Request.getLaundryModel(),1)); //洗衣模式
        entityYhMqtt0607.setTime(new Date());
        entityYhMqtt0607.setTimeHex(timeConvertToHex(entityYhMqtt0607.getTime(),4));
        entityYhMqtt0607.setConversionCode("00000000");
        String coinNum = DesUtils.intToHexWithFillZero(0,2); //投币数量，转16进制(需补零)
        String effectiveTime = DesUtils.intToHexWithFillZero(0,2);
        String freeTime = DesUtils.intToHexWithFillZero(0,2);

        String comStr = String.format("%s%s%s%s%s%s%s%s%s",entityYhMqtt0607.getOrderNoHex(),entityYhMqtt0607.getConsumptionModelHex(),entityYhMqtt0607.getBalanceHex(),entityYhMqtt0607.getLaundryModelHex(),coinNum,effectiveTime,freeTime,entityYhMqtt0607.getTimeHex(),entityYhMqtt0607.getConversionCode());
        String encDate2 = DesUtils.Cmd_Des(comStr,DesUtils.datakey);
        String encode = "060018" +encDate2+ DesUtils.xorStr("0018"+comStr);
        String raw = "060018" +comStr+ DesUtils.xorStr("0018"+comStr);
        entityYhMqtt0607.setEncryptionCommand(encode);  //加密后的指令
        entityYhMqtt0607.setUnencryptedCommand(raw);  //未加密的指令
        return entityYhMqtt0607;
    }

    public static EntityYhMqtt0606 convertYhMqtt0606(YhMqtt0606Request request){
        if(request.getTotalTime() > 60){
            throw new RuntimeException("参数错误");
        }
        if(ObjectUtil.isEmpty(request.getOverTime())){
            request.setOverTime(BigDecimal.ONE);
        }
        EntityYhMqtt0606 entityYhMqtt0606 = Convert.convert(EntityYhMqtt0606.class,request);
        entityYhMqtt0606.setOrderNoHex( DesUtils.intToHexWithFillZero(request.getOrderNo().intValue(),4));
        entityYhMqtt0606.setBalanceHex(DesUtils.intToHexWithFillZero(0,4)); //无用参数，直接填零
        entityYhMqtt0606.setTotalTime(60 * request.getTotalTime());
        entityYhMqtt0606.setTotalTimeHex(DesUtils.intToHexWithFillZero(entityYhMqtt0606.getTotalTime(),4));
        entityYhMqtt0606.setConsumptionModelHex("06");
        entityYhMqtt0606.setMinUnitHex("003C");
        entityYhMqtt0606.setDeductionRateHex("000001");
        entityYhMqtt0606.setOverTime(request.getOverTime().multiply(new BigDecimal(60)));
        entityYhMqtt0606.setOverTimeHex(DesUtils.intToHexWithFillZero(entityYhMqtt0606.getOverTime().intValue(),1));

        entityYhMqtt0606.setTime(new Date());
        entityYhMqtt0606.setTimeHex(timeConvertToHex(entityYhMqtt0606.getTime(),4));
        entityYhMqtt0606.setConversionCode("00000000");

        String comStr = String.format("%s%s%s%s%s%s%s%s%s",
                entityYhMqtt0606.getOrderNoHex(),
                entityYhMqtt0606.getConsumptionModelHex(),
                entityYhMqtt0606.getBalanceHex(),
                entityYhMqtt0606.getTotalTimeHex(),
                entityYhMqtt0606.getMinUnitHex(),
                entityYhMqtt0606.getDeductionRateHex(),
                entityYhMqtt0606.getOverTimeHex(),
                entityYhMqtt0606.getTimeHex(),
                entityYhMqtt0606.getConversionCode()
        );
        String encDate2 = DesUtils.Cmd_Des(comStr,DesUtils.datakey);
        String encode = "06001B" +encDate2+ DesUtils.xorStr("001B"+comStr);
        String raw = "06001B" +comStr+ DesUtils.xorStr("001B"+comStr);
        entityYhMqtt0606.setEncryptionCommand(encode);  //加密后的指令
        entityYhMqtt0606.setUnencryptedCommand(raw);  //未加密的指令
        return entityYhMqtt0606;
    }

    /**
     * 07数据转换
     * @param yhMqtt07Request
     * @return
     */
    public static EntityYhMqtt07 convertYhMqtt07(YhMqtt07Request yhMqtt07Request){
        EntityYhMqtt07 entityYhMqtt07 = Convert.convert(EntityYhMqtt07.class,yhMqtt07Request);
        entityYhMqtt07.setConvertCode(DesUtils.Cmd_DesRsn(yhMqtt07Request.getRandomCode(),DesUtils.rsnkey));
        entityYhMqtt07.setOrderNoHex(DesUtils.intToHexWithFillZero(yhMqtt07Request.getOrderNo().intValue(),4));
        String comStr= entityYhMqtt07.getOrderNoHex() + entityYhMqtt07.getConvertCode() ;
        String encDate2 = DesUtils.Cmd_Des(comStr,DesUtils.datakey);
        entityYhMqtt07.setEncryptionCommand("070008" +encDate2+ DesUtils.xorStr("0008"+comStr));
        entityYhMqtt07.setUnencryptedCommand("070008"+comStr+DesUtils.xorStr("0008"+comStr));

        return entityYhMqtt07;
    }

    /**
     * 8A数据转换
     * @param message
     * @return
     */
    public static EntityYhMqtt8A convertYhMqtt8A(String message){
        String resultMsg = checkMsg(message);

        String signalStrength = resultMsg.substring(14,16);
        String status = resultMsg.substring(16,18);
        String errorStatus = resultMsg.substring(18,20);
        String remainderTime = resultMsg.substring(20,28);
        EntityYhMqtt8A entityYhMqtt8A = new EntityYhMqtt8A();
        entityYhMqtt8A.setStatusHex(status);
        entityYhMqtt8A.setRemainderTimeHex(remainderTime);
        entityYhMqtt8A.setErrorStatusHex(errorStatus);
        entityYhMqtt8A.setSignalStrengthHex(signalStrength);
        entityYhMqtt8A.setSignalStrength(DesUtils.hexToInt(signalStrength));
        entityYhMqtt8A.setRemainderTime(DesUtils.hexToInt(entityYhMqtt8A.getRemainderTimeHex()));
        entityYhMqtt8A.setErrorStatus(DesUtils.hexToInt(entityYhMqtt8A.getErrorStatusHex()));
        entityYhMqtt8A.setStatus(Integer.parseInt(entityYhMqtt8A.getStatusHex()));
        entityYhMqtt8A.setRaw(message);
        entityYhMqtt8A.setUnencryptedCommand(resultMsg);
        return entityYhMqtt8A;
    }

    public static EntityYhMqtt87 convertYhMqtt87(String message){
        String resultMsg = checkMsg(message);
        String orderNo = resultMsg.substring(12,20);
        String status = resultMsg.substring(20,22);
        EntityYhMqtt87 entityYhMqtt87 = new EntityYhMqtt87();
        entityYhMqtt87.setOrderNoHex(orderNo);
        entityYhMqtt87.setStatus(Integer.parseInt(status));
        entityYhMqtt87.setStatusHex(status);
        entityYhMqtt87.setOrderNo(DesUtils.hexToInt(orderNo).longValue());
        return entityYhMqtt87;
    }

    public static EntityYhMqtt060E convertYhMqtt060E(YhMqtt060ERequest yhMqtt060ERequest){
        return null;
    }

    public static String checkMsg(String msg){
        String body = msg.substring(6, msg.length() - 2);
        String len = msg.substring(2,6);
        System.out.println(len);
        String enx = msg.substring(msg.length() - 2);

        String org = DesUtils.Cmd_UnDes(body,DesUtils.datakey);

        String enx1 =DesUtils.xorStr(len+org);
        if(!enx.equals(enx1)){
            throw new RuntimeException(msg+",异或和检测不过");
        }
        return org;
    }
}
